Downloading the data
from google.colab import files
files.upload()
Saving kaggle.json to kaggle.json
{'kaggle.json': b'{"username":"dharanipoojitha","key":"8a5a919b6d23ed7c797c31a53d8eecdd"}'}
!mkdir ~/.kaggle
!cp kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
!kaggle competitions download -c dogs-vs-cats
Downloading dogs-vs-cats.zip to /content 100% 809M/812M [00:09<00:00, 60.2MB/s] 100% 812M/812M [00:09<00:00, 92.5MB/s]
!unzip -qq dogs-vs-cats.zip
!unzip -qq train.zip
Copying images to training, validation, and test directories
import os, shutil, pathlib
original_dir = pathlib.Path("train")
new_base_dir = pathlib.Path("cats_vs_dogs")
def make_subset(subset_name, start_index, end_index):
for category in ("cat", "dog"):
dir = new_base_dir / subset_name / category
os.makedirs(dir)
fnames = [f"{category}.{i}.jpg" for i in range(start_index, end_index)]
for fname in fnames:
shutil.copyfile(src=original_dir / fname,
dst=dir / fname)
Let us train a model from scratch. The model 1 has a Training sample of 1000, a Validation sample of 500, and a Test sample of 500.
from tensorflow.keras.utils import image_dataset_from_directory
make_subset("train", start_index=0, end_index=1000)
make_subset("validation", start_index=1000, end_index=1500)
make_subset("test", start_index=1500, end_index=2000)
train_dataset = image_dataset_from_directory(
new_base_dir / "train",
image_size=(180, 180),
batch_size=32)
validation_dataset = image_dataset_from_directory(
new_base_dir / "validation",
image_size=(180, 180),
batch_size=32)
test_dataset = image_dataset_from_directory(
new_base_dir / "test",
image_size=(180, 180),
batch_size=32)
import numpy as np
import tensorflow as tf
random_numbers = np.random.normal(size=(1000, 16))
dataset = tf.data.Dataset.from_tensor_slices(random_numbers)
for i, element in enumerate(dataset):
print(element.shape)
if i >= 2:
break
batched_dataset = dataset.batch(32)
for i, element in enumerate(batched_dataset):
print(element.shape)
if i >= 2:
break
reshaped_dataset = dataset.map(lambda x: tf.reshape(x, (4, 4)))
for i, element in enumerate(reshaped_dataset):
print(element.shape)
if i >= 2:
break
for data_batch, labels_batch in train_dataset:
print("data batch shape:", data_batch.shape)
print("labels batch shape:", labels_batch.shape)
break
Found 2000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. (16,) (16,) (16,) (32, 16) (32, 16) (32, 16) (4, 4) (4, 4) (4, 4) data batch shape: (32, 180, 180, 3) labels batch shape: (32,)
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = layers.Rescaling(1./255)(inputs)
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.Flatten()(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.summary()
model.compile(loss="binary_crossentropy",
optimizer="rmsprop",
metrics=["accuracy"])
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="convnet_from_scratch.keras",
save_best_only=True,
monitor="val_loss")
]
history = model.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
test_model = keras.models.load_model("convnet_from_scratch.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Model: "functional_1"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ input_layer_1 (InputLayer) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ rescaling (Rescaling) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d (Conv2D) │ (None, 178, 178, 32) │ 896 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d (MaxPooling2D) │ (None, 89, 89, 32) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_1 (Conv2D) │ (None, 87, 87, 64) │ 18,496 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_1 (MaxPooling2D) │ (None, 43, 43, 64) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_2 (Conv2D) │ (None, 41, 41, 128) │ 73,856 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_2 (MaxPooling2D) │ (None, 20, 20, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_3 (Conv2D) │ (None, 18, 18, 256) │ 295,168 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_3 (MaxPooling2D) │ (None, 9, 9, 256) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_4 (Conv2D) │ (None, 7, 7, 256) │ 590,080 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ flatten (Flatten) │ (None, 12544) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense (Dense) │ (None, 1) │ 12,545 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 991,041 (3.78 MB)
Trainable params: 991,041 (3.78 MB)
Non-trainable params: 0 (0.00 B)
Epoch 1/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 18s 168ms/step - accuracy: 0.4879 - loss: 0.7983 - val_accuracy: 0.5000 - val_loss: 0.6928 Epoch 2/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 52ms/step - accuracy: 0.5183 - loss: 0.6937 - val_accuracy: 0.5000 - val_loss: 0.7191 Epoch 3/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 53ms/step - accuracy: 0.5117 - loss: 0.6950 - val_accuracy: 0.5450 - val_loss: 0.6823 Epoch 4/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 102ms/step - accuracy: 0.5639 - loss: 0.6777 - val_accuracy: 0.5650 - val_loss: 0.6707 Epoch 5/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 52ms/step - accuracy: 0.6207 - loss: 0.6344 - val_accuracy: 0.6650 - val_loss: 0.6364 Epoch 6/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 84ms/step - accuracy: 0.6728 - loss: 0.6343 - val_accuracy: 0.6370 - val_loss: 0.6479 Epoch 7/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 51ms/step - accuracy: 0.6889 - loss: 0.6052 - val_accuracy: 0.6240 - val_loss: 0.6903 Epoch 8/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 6s 89ms/step - accuracy: 0.7225 - loss: 0.5634 - val_accuracy: 0.7020 - val_loss: 0.5764 Epoch 9/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 58ms/step - accuracy: 0.7469 - loss: 0.5118 - val_accuracy: 0.6370 - val_loss: 0.7865 Epoch 10/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 6s 80ms/step - accuracy: 0.7490 - loss: 0.5311 - val_accuracy: 0.7050 - val_loss: 0.5587 Epoch 11/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 72ms/step - accuracy: 0.7719 - loss: 0.4785 - val_accuracy: 0.7010 - val_loss: 0.5701 Epoch 12/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 51ms/step - accuracy: 0.7946 - loss: 0.4269 - val_accuracy: 0.6980 - val_loss: 0.6614 Epoch 13/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 52ms/step - accuracy: 0.8319 - loss: 0.3848 - val_accuracy: 0.6740 - val_loss: 0.7369 Epoch 14/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 6s 88ms/step - accuracy: 0.8512 - loss: 0.3417 - val_accuracy: 0.6990 - val_loss: 0.6296 Epoch 15/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 59ms/step - accuracy: 0.8912 - loss: 0.2583 - val_accuracy: 0.7140 - val_loss: 0.7621 Epoch 16/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 93ms/step - accuracy: 0.8979 - loss: 0.2473 - val_accuracy: 0.7250 - val_loss: 0.7721 Epoch 17/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 57ms/step - accuracy: 0.9231 - loss: 0.1806 - val_accuracy: 0.6820 - val_loss: 1.0768 Epoch 18/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 53ms/step - accuracy: 0.9286 - loss: 0.1723 - val_accuracy: 0.7320 - val_loss: 1.0399 Epoch 19/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 103ms/step - accuracy: 0.9522 - loss: 0.1136 - val_accuracy: 0.7050 - val_loss: 1.2337 Epoch 20/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 52ms/step - accuracy: 0.9668 - loss: 0.1011 - val_accuracy: 0.7080 - val_loss: 1.2973 Epoch 21/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 52ms/step - accuracy: 0.9586 - loss: 0.1113 - val_accuracy: 0.7290 - val_loss: 1.2266 Epoch 22/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 71ms/step - accuracy: 0.9739 - loss: 0.0663 - val_accuracy: 0.7100 - val_loss: 1.4523 Epoch 23/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 67ms/step - accuracy: 0.9704 - loss: 0.0674 - val_accuracy: 0.7100 - val_loss: 1.6233 Epoch 24/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 57ms/step - accuracy: 0.9801 - loss: 0.0689 - val_accuracy: 0.7260 - val_loss: 1.5360 Epoch 25/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 56ms/step - accuracy: 0.9713 - loss: 0.1040 - val_accuracy: 0.6980 - val_loss: 1.8070 Epoch 26/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 86ms/step - accuracy: 0.9869 - loss: 0.0413 - val_accuracy: 0.6810 - val_loss: 2.1662 Epoch 27/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 58ms/step - accuracy: 0.9813 - loss: 0.0596 - val_accuracy: 0.7160 - val_loss: 1.9012 Epoch 28/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 69ms/step - accuracy: 0.9841 - loss: 0.0507 - val_accuracy: 0.7040 - val_loss: 2.0670 Epoch 29/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 66ms/step - accuracy: 0.9819 - loss: 0.0441 - val_accuracy: 0.7260 - val_loss: 1.8001 Epoch 30/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 53ms/step - accuracy: 0.9961 - loss: 0.0132 - val_accuracy: 0.6970 - val_loss: 2.2206 Epoch 31/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 52ms/step - accuracy: 0.9852 - loss: 0.0573 - val_accuracy: 0.7090 - val_loss: 2.1233 Epoch 32/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 79ms/step - accuracy: 0.9740 - loss: 0.0889 - val_accuracy: 0.7020 - val_loss: 2.0830 Epoch 33/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 63ms/step - accuracy: 0.9947 - loss: 0.0308 - val_accuracy: 0.6850 - val_loss: 2.1733 Epoch 34/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 5s 59ms/step - accuracy: 0.9947 - loss: 0.0230 - val_accuracy: 0.7040 - val_loss: 2.2599 Epoch 35/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 86ms/step - accuracy: 0.9900 - loss: 0.0293 - val_accuracy: 0.7150 - val_loss: 2.3724 Epoch 36/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 62ms/step - accuracy: 0.9845 - loss: 0.0595 - val_accuracy: 0.7300 - val_loss: 2.4565 Epoch 37/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 54ms/step - accuracy: 0.9858 - loss: 0.0554 - val_accuracy: 0.6960 - val_loss: 2.5770 Epoch 38/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 57ms/step - accuracy: 0.9926 - loss: 0.0336 - val_accuracy: 0.6960 - val_loss: 2.5435 Epoch 39/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 81ms/step - accuracy: 0.9915 - loss: 0.0344 - val_accuracy: 0.7090 - val_loss: 2.7056 Epoch 40/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 52ms/step - accuracy: 0.9979 - loss: 0.0135 - val_accuracy: 0.6920 - val_loss: 2.6403 Epoch 41/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 81ms/step - accuracy: 0.9831 - loss: 0.0548 - val_accuracy: 0.7200 - val_loss: 2.4621 Epoch 42/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 53ms/step - accuracy: 0.9894 - loss: 0.0618 - val_accuracy: 0.7190 - val_loss: 2.7350 Epoch 43/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 6s 93ms/step - accuracy: 0.9913 - loss: 0.0399 - val_accuracy: 0.7080 - val_loss: 2.8345 Epoch 44/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 8s 53ms/step - accuracy: 0.9919 - loss: 0.0377 - val_accuracy: 0.7090 - val_loss: 2.6473 Epoch 45/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 78ms/step - accuracy: 0.9946 - loss: 0.0239 - val_accuracy: 0.7000 - val_loss: 2.7864 Epoch 46/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 4s 71ms/step - accuracy: 0.9897 - loss: 0.0310 - val_accuracy: 0.7070 - val_loss: 3.0391 Epoch 47/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 51ms/step - accuracy: 0.9917 - loss: 0.0314 - val_accuracy: 0.7020 - val_loss: 3.2215 Epoch 48/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 3s 53ms/step - accuracy: 0.9842 - loss: 0.0529 - val_accuracy: 0.7390 - val_loss: 2.5755 Epoch 49/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 7s 84ms/step - accuracy: 0.9799 - loss: 0.0524 - val_accuracy: 0.7050 - val_loss: 3.3300 Epoch 50/50 63/63 ━━━━━━━━━━━━━━━━━━━━ 9s 58ms/step - accuracy: 0.9915 - loss: 0.0348 - val_accuracy: 0.6860 - val_loss: 3.4859 32/32 ━━━━━━━━━━━━━━━━━━━━ 3s 63ms/step - accuracy: 0.6776 - loss: 0.6002 Test accuracy: 0.681
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
For the second model we are increasing training sample and keeping validation sample of 500, and a test sample of 500.
from tensorflow.keras.utils import image_dataset_from_directory
make_subset("train_2", start_index=0, end_index=3000)
make_subset("validation_2", start_index=3000, end_index=3500)
make_subset("test_2", start_index=3500, end_index=4000)
train_dataset = image_dataset_from_directory(
new_base_dir / "train_2",
image_size=(180, 180),
batch_size=32)
validation_dataset = image_dataset_from_directory(
new_base_dir / "validation_2",
image_size=(180, 180),
batch_size=32)
test_dataset = image_dataset_from_directory(
new_base_dir / "test_2",
image_size=(180, 180),
batch_size=32)
Found 6000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. Found 1000 files belonging to 2 classes.
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
from keras.callbacks import EarlyStopping
from keras import regularizers
# Define early_stopping_monitor
# used early stopping to stop optimization when it isn't helping any more.
early_stopping_monitor = EarlyStopping(patience=10)
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
inputs = keras.Input(shape=(180, 180, 3))
x = layers.Rescaling(1./255)(inputs)
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu",kernel_regularizer = regularizers.l2(l2=0.01))(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.summary()
model.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
metrics=["accuracy"])
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="convnet_from_scratch.keras",
save_best_only=True,
monitor="val_loss"), early_stopping_monitor
]
history = model.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
test_model = keras.models.load_model("convnet_from_scratch.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Model: "functional_5"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ input_layer_7 (InputLayer) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ rescaling_3 (Rescaling) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_13 (Conv2D) │ (None, 178, 178, 32) │ 896 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_12 (MaxPooling2D) │ (None, 89, 89, 32) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_14 (Conv2D) │ (None, 87, 87, 64) │ 18,496 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_13 (MaxPooling2D) │ (None, 43, 43, 64) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_15 (Conv2D) │ (None, 41, 41, 128) │ 73,856 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_14 (MaxPooling2D) │ (None, 20, 20, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_16 (Conv2D) │ (None, 18, 18, 256) │ 295,168 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_15 (MaxPooling2D) │ (None, 9, 9, 256) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_17 (Conv2D) │ (None, 7, 7, 256) │ 590,080 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ flatten_1 (Flatten) │ (None, 12544) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout (Dropout) │ (None, 12544) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_1 (Dense) │ (None, 1) │ 12,545 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 991,041 (3.78 MB)
Trainable params: 991,041 (3.78 MB)
Non-trainable params: 0 (0.00 B)
Epoch 1/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 20s 81ms/step - accuracy: 0.5150 - loss: 1.2166 - val_accuracy: 0.5960 - val_loss: 0.6718 Epoch 2/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 42ms/step - accuracy: 0.6040 - loss: 0.6689 - val_accuracy: 0.6120 - val_loss: 0.6713 Epoch 3/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 56ms/step - accuracy: 0.6495 - loss: 0.6408 - val_accuracy: 0.6970 - val_loss: 0.5784 Epoch 4/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 55ms/step - accuracy: 0.6754 - loss: 0.6129 - val_accuracy: 0.7180 - val_loss: 0.5548 Epoch 5/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 9s 46ms/step - accuracy: 0.6951 - loss: 0.5812 - val_accuracy: 0.6950 - val_loss: 0.5716 Epoch 6/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 57ms/step - accuracy: 0.7407 - loss: 0.5373 - val_accuracy: 0.6990 - val_loss: 0.5829 Epoch 7/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 8s 42ms/step - accuracy: 0.7546 - loss: 0.5210 - val_accuracy: 0.7160 - val_loss: 0.5793 Epoch 8/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 48ms/step - accuracy: 0.7693 - loss: 0.4892 - val_accuracy: 0.7420 - val_loss: 0.5401 Epoch 9/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 12s 56ms/step - accuracy: 0.7814 - loss: 0.4681 - val_accuracy: 0.7980 - val_loss: 0.4411 Epoch 10/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 9s 46ms/step - accuracy: 0.7971 - loss: 0.4541 - val_accuracy: 0.8000 - val_loss: 0.4479 Epoch 11/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 45ms/step - accuracy: 0.8149 - loss: 0.4262 - val_accuracy: 0.7540 - val_loss: 0.5874 Epoch 12/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 13s 58ms/step - accuracy: 0.8309 - loss: 0.4019 - val_accuracy: 0.7750 - val_loss: 0.4997 Epoch 13/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 51ms/step - accuracy: 0.8397 - loss: 0.3919 - val_accuracy: 0.7910 - val_loss: 0.4734 Epoch 14/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 48ms/step - accuracy: 0.8451 - loss: 0.3708 - val_accuracy: 0.8470 - val_loss: 0.3971 Epoch 15/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 12s 59ms/step - accuracy: 0.8597 - loss: 0.3412 - val_accuracy: 0.7520 - val_loss: 0.7066 Epoch 16/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 9s 46ms/step - accuracy: 0.8688 - loss: 0.3320 - val_accuracy: 0.8210 - val_loss: 0.4748 Epoch 17/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 10s 46ms/step - accuracy: 0.8804 - loss: 0.3105 - val_accuracy: 0.8450 - val_loss: 0.4051 Epoch 18/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 57ms/step - accuracy: 0.8977 - loss: 0.2840 - val_accuracy: 0.8350 - val_loss: 0.4304 Epoch 19/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 8s 43ms/step - accuracy: 0.9009 - loss: 0.2639 - val_accuracy: 0.8160 - val_loss: 0.5621 Epoch 20/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 59ms/step - accuracy: 0.9064 - loss: 0.2471 - val_accuracy: 0.8210 - val_loss: 0.6066 Epoch 21/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 18s 45ms/step - accuracy: 0.9168 - loss: 0.2345 - val_accuracy: 0.8760 - val_loss: 0.3988 Epoch 22/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 12s 56ms/step - accuracy: 0.9269 - loss: 0.2103 - val_accuracy: 0.8580 - val_loss: 0.4465 Epoch 23/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 18s 42ms/step - accuracy: 0.9360 - loss: 0.1846 - val_accuracy: 0.7500 - val_loss: 0.8665 Epoch 24/50 188/188 ━━━━━━━━━━━━━━━━━━━━ 11s 56ms/step - accuracy: 0.9409 - loss: 0.1769 - val_accuracy: 0.8190 - val_loss: 0.5828 32/32 ━━━━━━━━━━━━━━━━━━━━ 2s 40ms/step - accuracy: 0.8118 - loss: 0.4407 Test accuracy: 0.812
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
Now, the third model will have 9000 training samples we will keep the same validation sample of 500, and a test sample of 500.
from tensorflow.keras.utils import image_dataset_from_directory
make_subset("train_3", start_index=0, end_index=9000)
make_subset("validation_3", start_index=9000, end_index=9500)
make_subset("test_3", start_index=9500, end_index=10000)
train_dataset = image_dataset_from_directory(
new_base_dir / "train_3",
image_size=(180, 180),
batch_size=32)
validation_dataset = image_dataset_from_directory(
new_base_dir / "validation_3",
image_size=(180, 180),
batch_size=32)
test_dataset = image_dataset_from_directory(
new_base_dir / "test_3",
image_size=(180, 180),
batch_size=32)
Found 18000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. Found 1000 files belonging to 2 classes.
from tensorflow import keras
from tensorflow.keras import layers
import matplotlib.pyplot as plt
from keras.callbacks import EarlyStopping
from keras import regularizers
# Define early_stopping_monitor
# used early stopping to stop optimization when it isn't helping any more.
early_stopping_monitor = EarlyStopping(patience=10)
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
inputs = keras.Input(shape=(180, 180, 3))
x = layers.Rescaling(1./255)(inputs)
x = layers.Conv2D(filters=32, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=64, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=128, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu")(x)
x = layers.MaxPooling2D(pool_size=2)(x)
x = layers.Conv2D(filters=256, kernel_size=3, activation="relu", kernel_regularizer=regularizers.l2(0.01))(x)
x = layers.Flatten()(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.summary()
model.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
metrics=["accuracy"])
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="convnet_from_scratch.keras",
save_best_only=True,
monitor="val_loss"), early_stopping_monitor
]
history = model.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
test_model = keras.models.load_model("convnet_from_scratch.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Model: "functional_8"
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━┓ ┃ Layer (type) ┃ Output Shape ┃ Param # ┃ ┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━┩ │ input_layer_11 (InputLayer) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ rescaling_5 (Rescaling) │ (None, 180, 180, 3) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_22 (Conv2D) │ (None, 178, 178, 32) │ 896 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_20 (MaxPooling2D) │ (None, 89, 89, 32) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_23 (Conv2D) │ (None, 87, 87, 64) │ 18,496 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_21 (MaxPooling2D) │ (None, 43, 43, 64) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_24 (Conv2D) │ (None, 41, 41, 128) │ 73,856 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_22 (MaxPooling2D) │ (None, 20, 20, 128) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_25 (Conv2D) │ (None, 18, 18, 256) │ 295,168 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ max_pooling2d_23 (MaxPooling2D) │ (None, 9, 9, 256) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ conv2d_26 (Conv2D) │ (None, 7, 7, 256) │ 590,080 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ flatten_2 (Flatten) │ (None, 12544) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dropout_1 (Dropout) │ (None, 12544) │ 0 │ ├──────────────────────────────────────┼─────────────────────────────┼─────────────────┤ │ dense_2 (Dense) │ (None, 1) │ 12,545 │ └──────────────────────────────────────┴─────────────────────────────┴─────────────────┘
Total params: 991,041 (3.78 MB)
Trainable params: 991,041 (3.78 MB)
Non-trainable params: 0 (0.00 B)
Epoch 1/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 34s 54ms/step - accuracy: 0.5414 - loss: 0.9275 - val_accuracy: 0.6840 - val_loss: 0.6082 Epoch 2/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 37s 49ms/step - accuracy: 0.6754 - loss: 0.6126 - val_accuracy: 0.6850 - val_loss: 0.5913 Epoch 3/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 40s 47ms/step - accuracy: 0.7275 - loss: 0.5496 - val_accuracy: 0.7630 - val_loss: 0.4997 Epoch 4/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 40s 44ms/step - accuracy: 0.7703 - loss: 0.5002 - val_accuracy: 0.8140 - val_loss: 0.4364 Epoch 5/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 48ms/step - accuracy: 0.7990 - loss: 0.4561 - val_accuracy: 0.8160 - val_loss: 0.4218 Epoch 6/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 40s 46ms/step - accuracy: 0.8256 - loss: 0.4131 - val_accuracy: 0.8320 - val_loss: 0.3800 Epoch 7/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 39s 43ms/step - accuracy: 0.8417 - loss: 0.3805 - val_accuracy: 0.8400 - val_loss: 0.3747 Epoch 8/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 49ms/step - accuracy: 0.8527 - loss: 0.3529 - val_accuracy: 0.8660 - val_loss: 0.3398 Epoch 9/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 25s 44ms/step - accuracy: 0.8717 - loss: 0.3237 - val_accuracy: 0.8930 - val_loss: 0.2908 Epoch 10/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 44ms/step - accuracy: 0.8812 - loss: 0.2988 - val_accuracy: 0.8420 - val_loss: 0.4357 Epoch 11/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 44s 48ms/step - accuracy: 0.8975 - loss: 0.2694 - val_accuracy: 0.8850 - val_loss: 0.2984 Epoch 12/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 49ms/step - accuracy: 0.9002 - loss: 0.2541 - val_accuracy: 0.8970 - val_loss: 0.3370 Epoch 13/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 25s 44ms/step - accuracy: 0.9150 - loss: 0.2346 - val_accuracy: 0.8870 - val_loss: 0.3108 Epoch 14/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 48ms/step - accuracy: 0.9222 - loss: 0.2133 - val_accuracy: 0.8310 - val_loss: 0.5047 Epoch 15/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 26s 45ms/step - accuracy: 0.9244 - loss: 0.2045 - val_accuracy: 0.9110 - val_loss: 0.2770 Epoch 16/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 40s 43ms/step - accuracy: 0.9310 - loss: 0.1947 - val_accuracy: 0.8940 - val_loss: 0.3078 Epoch 17/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 45ms/step - accuracy: 0.9319 - loss: 0.1917 - val_accuracy: 0.9190 - val_loss: 0.2534 Epoch 18/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 47ms/step - accuracy: 0.9413 - loss: 0.1671 - val_accuracy: 0.8540 - val_loss: 0.5537 Epoch 19/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 39s 45ms/step - accuracy: 0.9394 - loss: 0.1880 - val_accuracy: 0.8980 - val_loss: 0.3657 Epoch 20/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 44ms/step - accuracy: 0.9435 - loss: 0.1628 - val_accuracy: 0.9170 - val_loss: 0.2956 Epoch 21/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 49ms/step - accuracy: 0.9462 - loss: 0.1617 - val_accuracy: 0.8840 - val_loss: 0.3211 Epoch 22/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 38s 43ms/step - accuracy: 0.9534 - loss: 0.1485 - val_accuracy: 0.9080 - val_loss: 0.2676 Epoch 23/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 43ms/step - accuracy: 0.9510 - loss: 0.1504 - val_accuracy: 0.8740 - val_loss: 0.3851 Epoch 24/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 43s 47ms/step - accuracy: 0.9556 - loss: 0.1407 - val_accuracy: 0.8960 - val_loss: 0.3337 Epoch 25/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 48ms/step - accuracy: 0.9600 - loss: 0.1280 - val_accuracy: 0.9050 - val_loss: 0.3987 Epoch 26/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 39s 44ms/step - accuracy: 0.9567 - loss: 0.1336 - val_accuracy: 0.9160 - val_loss: 0.3582 Epoch 27/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 44ms/step - accuracy: 0.9595 - loss: 0.1358 - val_accuracy: 0.9120 - val_loss: 0.3532 32/32 ━━━━━━━━━━━━━━━━━━━━ 2s 45ms/step - accuracy: 0.8873 - loss: 0.3022 Test accuracy: 0.896
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
Pretrained Model 1 : Training sample of 2000, a validation sample of 1000, and a test sample of 1000.
VGG16 Pretrained Convnet Network
Using Feature Extraction with Data Augmentation and Fine-tuning
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers
# Instantiating the VGG16 convolutional base
conv_base = keras.applications.vgg16.VGG16(
weights="imagenet",
include_top=False)
# Freezing all layers until the fourth from the last
conv_base.trainable = True
for layer in conv_base.layers[:-4]:
layer.trainable = False
# Adding a data augmentation stage and a classifier to the convolutional base
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = keras.applications.vgg16.preprocess_input(x)
x = conv_base(x)
x = layers.Flatten()(x)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model_pre_trained_1 = keras.Model(inputs, outputs)
# Fine-tuning the model
model_pre_trained_1.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.RMSprop(learning_rate=1e-6),
metrics=["accuracy"])
# Used early stopping to stop optimization
early_stopping_monitor = EarlyStopping(patience=10)
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="convnet_from_scratch.keras",
save_best_only=True,
monitor="val_loss"), early_stopping_monitor
]
history = model.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
plt.show()
test_model = keras.models.load_model("convnet_from_scratch.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/vgg16/vgg16_weights_tf_dim_ordering_tf_kernels_notop.h5 58889256/58889256 ━━━━━━━━━━━━━━━━━━━━ 0s 0us/step Epoch 1/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 28s 49ms/step - accuracy: 0.9561 - loss: 0.1402 - val_accuracy: 0.8800 - val_loss: 0.4756 Epoch 2/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 38s 43ms/step - accuracy: 0.9565 - loss: 0.1520 - val_accuracy: 0.9080 - val_loss: 0.3930 Epoch 3/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 27s 48ms/step - accuracy: 0.9599 - loss: 0.1313 - val_accuracy: 0.8920 - val_loss: 0.4743 Epoch 4/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 39s 45ms/step - accuracy: 0.9618 - loss: 0.1313 - val_accuracy: 0.9000 - val_loss: 0.4542 Epoch 5/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 26s 46ms/step - accuracy: 0.9625 - loss: 0.1256 - val_accuracy: 0.8950 - val_loss: 0.3894 Epoch 6/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 48ms/step - accuracy: 0.9587 - loss: 0.1380 - val_accuracy: 0.9100 - val_loss: 0.2933 Epoch 7/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 25s 44ms/step - accuracy: 0.9659 - loss: 0.1242 - val_accuracy: 0.9040 - val_loss: 0.4461 Epoch 8/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 45ms/step - accuracy: 0.9621 - loss: 0.1268 - val_accuracy: 0.8820 - val_loss: 0.4899 Epoch 9/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 47ms/step - accuracy: 0.9631 - loss: 0.1363 - val_accuracy: 0.8720 - val_loss: 0.8799 Epoch 10/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 41s 48ms/step - accuracy: 0.9651 - loss: 0.1281 - val_accuracy: 0.8950 - val_loss: 0.3202 Epoch 11/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 38s 43ms/step - accuracy: 0.9662 - loss: 0.1312 - val_accuracy: 0.9000 - val_loss: 0.3921 Epoch 12/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 42s 45ms/step - accuracy: 0.9601 - loss: 0.1477 - val_accuracy: 0.9000 - val_loss: 0.4189 Epoch 13/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 43s 49ms/step - accuracy: 0.9639 - loss: 0.1236 - val_accuracy: 0.8190 - val_loss: 1.4806 Epoch 14/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 26s 47ms/step - accuracy: 0.9669 - loss: 0.1274 - val_accuracy: 0.9220 - val_loss: 0.3507 Epoch 15/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 39s 44ms/step - accuracy: 0.9679 - loss: 0.1281 - val_accuracy: 0.9040 - val_loss: 0.4525 Epoch 16/50 563/563 ━━━━━━━━━━━━━━━━━━━━ 43s 47ms/step - accuracy: 0.9675 - loss: 0.1240 - val_accuracy: 0.8790 - val_loss: 0.4057
32/32 ━━━━━━━━━━━━━━━━━━━━ 2s 44ms/step - accuracy: 0.9290 - loss: 0.2517 Test accuracy: 0.916
# Plotting the results
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
Pretrained Model 2: ResNet50V2 convolutional base
import os
import shutil
import pathlib
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow.keras.models import Sequential
from tensorflow.keras.callbacks import ModelCheckpoint
original_dir = pathlib.Path("train")
new_base_dir = pathlib.Path("cats_vs_dogs_small_3")
def make_subset(subset_name, start_index, end_index):
for category in ("cat", "dog"):
dir = new_base_dir / subset_name / category
os.makedirs(dir, exist_ok=True)
fnames = [f"{category}.{i}.jpg" for i in range(start_index, end_index)]
for fname in fnames:
shutil.copyfile(src=original_dir / fname, dst=dir / fname)
make_subset("validation", start_index=0, end_index=500)
make_subset("test", start_index=500, end_index=1000)
make_subset("train", start_index=1000, end_index=5000)
train_dataset = tf.keras.utils.image_dataset_from_directory(
new_base_dir / "train",
image_size=(180, 180),
batch_size=32)
validation_dataset = tf.keras.utils.image_dataset_from_directory(
new_base_dir / "validation",
image_size=(180, 180),
batch_size=32)
test_dataset = tf.keras.utils.image_dataset_from_directory(
new_base_dir / "test",
image_size=(180, 180),
batch_size=32)
model = Sequential([
layers.Conv2D(32, (3, 3), activation='relu', input_shape=(180, 180, 3)),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(64, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Conv2D(128, (3, 3), activation='relu'),
layers.MaxPooling2D((2, 2)),
layers.Flatten(),
layers.Dense(512, activation='relu'),
layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
callbacks = [
ModelCheckpoint(
filepath="convnet_from_scratch_with_augmentation_4000.keras",
save_best_only=True,
monitor="val_loss")
]
history = model.fit(
train_dataset,
epochs=20,
validation_data=validation_dataset,
callbacks=callbacks)
Found 8000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. Found 1000 files belonging to 2 classes. Epoch 1/20
/usr/local/lib/python3.10/dist-packages/keras/src/layers/convolutional/base_conv.py:107: UserWarning: Do not pass an `input_shape`/`input_dim` argument to a layer. When using Sequential models, prefer using an `Input(shape)` object as the first layer in the model instead. super().__init__(activity_regularizer=activity_regularizer, **kwargs)
250/250 ━━━━━━━━━━━━━━━━━━━━ 20s 59ms/step - accuracy: 0.5465 - loss: 14.0708 - val_accuracy: 0.5340 - val_loss: 0.7383 Epoch 2/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 50ms/step - accuracy: 0.6005 - loss: 0.6607 - val_accuracy: 0.6330 - val_loss: 0.6335 Epoch 3/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 11s 43ms/step - accuracy: 0.6366 - loss: 0.6237 - val_accuracy: 0.6200 - val_loss: 0.6634 Epoch 4/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 23s 52ms/step - accuracy: 0.6644 - loss: 0.6047 - val_accuracy: 0.6880 - val_loss: 0.5736 Epoch 5/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 47ms/step - accuracy: 0.6993 - loss: 0.5638 - val_accuracy: 0.7570 - val_loss: 0.5193 Epoch 6/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 21s 51ms/step - accuracy: 0.7364 - loss: 0.5249 - val_accuracy: 0.6960 - val_loss: 0.6820 Epoch 7/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 20s 49ms/step - accuracy: 0.7763 - loss: 0.4711 - val_accuracy: 0.7350 - val_loss: 0.5486 Epoch 8/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 51ms/step - accuracy: 0.8005 - loss: 0.4272 - val_accuracy: 0.7570 - val_loss: 0.6025 Epoch 9/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 44ms/step - accuracy: 0.8313 - loss: 0.3723 - val_accuracy: 0.7610 - val_loss: 0.6047 Epoch 10/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 50ms/step - accuracy: 0.8706 - loss: 0.2950 - val_accuracy: 0.7800 - val_loss: 0.6965 Epoch 11/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 11s 44ms/step - accuracy: 0.8850 - loss: 0.2651 - val_accuracy: 0.7290 - val_loss: 0.8570 Epoch 12/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 48ms/step - accuracy: 0.8908 - loss: 0.2645 - val_accuracy: 0.7590 - val_loss: 1.0589 Epoch 13/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 52ms/step - accuracy: 0.9150 - loss: 0.2105 - val_accuracy: 0.7690 - val_loss: 1.1091 Epoch 14/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 20s 50ms/step - accuracy: 0.9307 - loss: 0.1823 - val_accuracy: 0.7240 - val_loss: 1.3294 Epoch 15/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 46ms/step - accuracy: 0.9337 - loss: 0.1812 - val_accuracy: 0.7550 - val_loss: 1.1651 Epoch 16/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 52ms/step - accuracy: 0.9459 - loss: 0.1443 - val_accuracy: 0.7620 - val_loss: 1.0986 Epoch 17/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 18s 40ms/step - accuracy: 0.9579 - loss: 0.1118 - val_accuracy: 0.7790 - val_loss: 1.1768 Epoch 18/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 50ms/step - accuracy: 0.9598 - loss: 0.1149 - val_accuracy: 0.7550 - val_loss: 1.2145 Epoch 19/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 50ms/step - accuracy: 0.9659 - loss: 0.1062 - val_accuracy: 0.7620 - val_loss: 1.5361 Epoch 20/20 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 48ms/step - accuracy: 0.9615 - loss: 0.1139 - val_accuracy: 0.7450 - val_loss: 1.2741
# Plotting the results
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()
Pretrained Model 3: MobileNetV2
import matplotlib.pyplot as plt
from tensorflow import keras
from tensorflow.keras import layers
# Instantiating the MobileNetV2 convolutional base
conv_base = keras.applications.MobileNetV2(
weights="imagenet",
include_top=False)
# Freezing all layers until fourth from the last
conv_base.trainable = True
for layer in conv_base.layers[:-4]:
layer.trainable = False
# Adding a data augmentation stage and a classifier to the convolutional base
data_augmentation = keras.Sequential(
[
layers.RandomFlip("horizontal"),
layers.RandomRotation(0.1),
layers.RandomZoom(0.2),
]
)
inputs = keras.Input(shape=(180, 180, 3))
x = data_augmentation(inputs)
x = keras.applications.mobilenet_v2.preprocess_input(x)
x = conv_base(x)
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dense(256)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1, activation="sigmoid")(x)
model_pre_trained_2 = keras.Model(inputs, outputs)
# Fine-tuning the model
model_pre_trained_2.compile(loss="binary_crossentropy",
optimizer=keras.optimizers.RMSprop(learning_rate=1e-6),
metrics=["accuracy"])
# Used early stopping to stop optimization
early_stopping_monitor = EarlyStopping(patience=10)
callbacks = [
keras.callbacks.ModelCheckpoint(
filepath="convnet_from_scratch_2.keras",
save_best_only=True,
monitor="val_loss"), early_stopping_monitor
]
history = model_pre_trained_2.fit(
train_dataset,
epochs=50,
validation_data=validation_dataset,
callbacks=callbacks)
plt.figure(figsize=(10, 10))
for images, _ in train_dataset.take(1):
for i in range(9):
augmented_images = data_augmentation(images)
ax = plt.subplot(3, 3, i + 1)
plt.imshow(augmented_images[0].numpy().astype("uint8"))
plt.axis("off")
plt.show()
# Evaluate the model on the test set
test_model = keras.models.load_model("convnet_from_scratch_2.keras")
test_loss, test_acc = test_model.evaluate(test_dataset)
print(f"Test accuracy: {test_acc:.3f}")
<ipython-input-25-f9dfafc74a43>:6: UserWarning: `input_shape` is undefined or non-square, or `rows` is not in [96, 128, 160, 192, 224]. Weights for input shape (224, 224) will be loaded as the default. conv_base = keras.applications.MobileNetV2(
Epoch 1/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 20s 61ms/step - accuracy: 0.6678 - loss: 0.6669 - val_accuracy: 0.8950 - val_loss: 0.2523 Epoch 2/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 54ms/step - accuracy: 0.8027 - loss: 0.4663 - val_accuracy: 0.9370 - val_loss: 0.1773 Epoch 3/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 55ms/step - accuracy: 0.8527 - loss: 0.3647 - val_accuracy: 0.9480 - val_loss: 0.1398 Epoch 4/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 56ms/step - accuracy: 0.8740 - loss: 0.3215 - val_accuracy: 0.9550 - val_loss: 0.1189 Epoch 5/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 53ms/step - accuracy: 0.8980 - loss: 0.2510 - val_accuracy: 0.9590 - val_loss: 0.1049 Epoch 6/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 48ms/step - accuracy: 0.9011 - loss: 0.2512 - val_accuracy: 0.9610 - val_loss: 0.0954 Epoch 7/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 51ms/step - accuracy: 0.9143 - loss: 0.2155 - val_accuracy: 0.9650 - val_loss: 0.0884 Epoch 8/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 21s 54ms/step - accuracy: 0.9260 - loss: 0.2024 - val_accuracy: 0.9710 - val_loss: 0.0830 Epoch 9/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 51ms/step - accuracy: 0.9251 - loss: 0.1935 - val_accuracy: 0.9730 - val_loss: 0.0790 Epoch 10/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 25s 70ms/step - accuracy: 0.9334 - loss: 0.1858 - val_accuracy: 0.9740 - val_loss: 0.0749 Epoch 11/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 16s 54ms/step - accuracy: 0.9372 - loss: 0.1733 - val_accuracy: 0.9760 - val_loss: 0.0718 Epoch 12/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 55ms/step - accuracy: 0.9389 - loss: 0.1612 - val_accuracy: 0.9790 - val_loss: 0.0693 Epoch 13/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 49ms/step - accuracy: 0.9395 - loss: 0.1574 - val_accuracy: 0.9820 - val_loss: 0.0671 Epoch 14/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 56ms/step - accuracy: 0.9418 - loss: 0.1611 - val_accuracy: 0.9820 - val_loss: 0.0652 Epoch 15/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 56ms/step - accuracy: 0.9421 - loss: 0.1591 - val_accuracy: 0.9820 - val_loss: 0.0632 Epoch 16/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 55ms/step - accuracy: 0.9418 - loss: 0.1593 - val_accuracy: 0.9820 - val_loss: 0.0617 Epoch 17/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 20s 55ms/step - accuracy: 0.9419 - loss: 0.1566 - val_accuracy: 0.9830 - val_loss: 0.0602 Epoch 18/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 18s 47ms/step - accuracy: 0.9452 - loss: 0.1433 - val_accuracy: 0.9830 - val_loss: 0.0591 Epoch 19/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 55ms/step - accuracy: 0.9446 - loss: 0.1493 - val_accuracy: 0.9840 - val_loss: 0.0580 Epoch 20/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 54ms/step - accuracy: 0.9481 - loss: 0.1388 - val_accuracy: 0.9840 - val_loss: 0.0566 Epoch 21/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 49ms/step - accuracy: 0.9494 - loss: 0.1426 - val_accuracy: 0.9830 - val_loss: 0.0556 Epoch 22/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 50ms/step - accuracy: 0.9431 - loss: 0.1418 - val_accuracy: 0.9830 - val_loss: 0.0545 Epoch 23/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 56ms/step - accuracy: 0.9474 - loss: 0.1404 - val_accuracy: 0.9830 - val_loss: 0.0539 Epoch 24/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 49ms/step - accuracy: 0.9474 - loss: 0.1469 - val_accuracy: 0.9830 - val_loss: 0.0531 Epoch 25/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 49ms/step - accuracy: 0.9460 - loss: 0.1487 - val_accuracy: 0.9830 - val_loss: 0.0529 Epoch 26/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 55ms/step - accuracy: 0.9522 - loss: 0.1292 - val_accuracy: 0.9830 - val_loss: 0.0526 Epoch 27/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 21s 55ms/step - accuracy: 0.9485 - loss: 0.1341 - val_accuracy: 0.9830 - val_loss: 0.0519 Epoch 28/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 18s 47ms/step - accuracy: 0.9519 - loss: 0.1291 - val_accuracy: 0.9830 - val_loss: 0.0515 Epoch 29/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 55ms/step - accuracy: 0.9528 - loss: 0.1394 - val_accuracy: 0.9830 - val_loss: 0.0505 Epoch 30/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 54ms/step - accuracy: 0.9513 - loss: 0.1305 - val_accuracy: 0.9830 - val_loss: 0.0499 Epoch 31/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 21s 55ms/step - accuracy: 0.9513 - loss: 0.1361 - val_accuracy: 0.9830 - val_loss: 0.0493 Epoch 32/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 55ms/step - accuracy: 0.9544 - loss: 0.1273 - val_accuracy: 0.9830 - val_loss: 0.0489 Epoch 33/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 50ms/step - accuracy: 0.9466 - loss: 0.1385 - val_accuracy: 0.9830 - val_loss: 0.0492 Epoch 34/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 46ms/step - accuracy: 0.9529 - loss: 0.1300 - val_accuracy: 0.9830 - val_loss: 0.0485 Epoch 35/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 54ms/step - accuracy: 0.9540 - loss: 0.1308 - val_accuracy: 0.9830 - val_loss: 0.0481 Epoch 36/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 53ms/step - accuracy: 0.9618 - loss: 0.1133 - val_accuracy: 0.9830 - val_loss: 0.0481 Epoch 37/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 19s 48ms/step - accuracy: 0.9562 - loss: 0.1190 - val_accuracy: 0.9830 - val_loss: 0.0480 Epoch 38/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 55ms/step - accuracy: 0.9572 - loss: 0.1145 - val_accuracy: 0.9830 - val_loss: 0.0477 Epoch 39/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 56ms/step - accuracy: 0.9537 - loss: 0.1186 - val_accuracy: 0.9830 - val_loss: 0.0473 Epoch 40/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 51ms/step - accuracy: 0.9521 - loss: 0.1294 - val_accuracy: 0.9830 - val_loss: 0.0467 Epoch 41/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 22s 55ms/step - accuracy: 0.9569 - loss: 0.1239 - val_accuracy: 0.9830 - val_loss: 0.0460 Epoch 42/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 15s 59ms/step - accuracy: 0.9569 - loss: 0.1149 - val_accuracy: 0.9830 - val_loss: 0.0459 Epoch 43/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 53ms/step - accuracy: 0.9556 - loss: 0.1219 - val_accuracy: 0.9830 - val_loss: 0.0459 Epoch 44/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 49ms/step - accuracy: 0.9565 - loss: 0.1223 - val_accuracy: 0.9840 - val_loss: 0.0460 Epoch 45/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 12s 49ms/step - accuracy: 0.9605 - loss: 0.1079 - val_accuracy: 0.9840 - val_loss: 0.0457 Epoch 46/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 55ms/step - accuracy: 0.9582 - loss: 0.1206 - val_accuracy: 0.9840 - val_loss: 0.0451 Epoch 47/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 18s 44ms/step - accuracy: 0.9516 - loss: 0.1286 - val_accuracy: 0.9840 - val_loss: 0.0452 Epoch 48/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 53ms/step - accuracy: 0.9525 - loss: 0.1302 - val_accuracy: 0.9840 - val_loss: 0.0452 Epoch 49/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 14s 54ms/step - accuracy: 0.9608 - loss: 0.1100 - val_accuracy: 0.9840 - val_loss: 0.0456 Epoch 50/50 250/250 ━━━━━━━━━━━━━━━━━━━━ 13s 54ms/step - accuracy: 0.9566 - loss: 0.1230 - val_accuracy: 0.9840 - val_loss: 0.0453
32/32 ━━━━━━━━━━━━━━━━━━━━ 5s 67ms/step - accuracy: 0.9729 - loss: 0.0547 Test accuracy: 0.981
# Plotting the results
accuracy = history.history["accuracy"]
val_accuracy = history.history["val_accuracy"]
loss = history.history["loss"]
val_loss = history.history["val_loss"]
epochs = range(1, len(accuracy) + 1)
plt.plot(epochs, accuracy, "bo", label="Training accuracy")
plt.plot(epochs, val_accuracy, "b", label="Validation accuracy")
plt.title("Training and validation accuracy")
plt.legend()
plt.figure()
plt.plot(epochs, loss, "bo", label="Training loss")
plt.plot(epochs, val_loss, "b", label="Validation loss")
plt.title("Training and validation loss")
plt.legend()
plt.show()